<?php

namespace App\Trip\Wechat\Pay\PayRes;

use App\Trip\Orders\Traits\ThrowErrorMessageTrait;
use App\Trip\Payment\PayQueryInterface;
use App\Trip\Wechat\Pay\Application;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use Exception;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @method string getAppId
 * @method string getOutTradeNo
 * @method string getTransactionId
 * @method bool isSuccess
 * @method  getTradeState
 * @method string getTradeStateDesc
 * @method string getSuccessAt
 * @method string getAttach
 * @method float getPayAmount
 * @method int getTotalFee
 * @method string getOpenId
 */
class PayQuery implements PayQueryInterface
{
    use ThrowErrorMessageTrait;

    private Application         $application;
    private HttpClientInterface $client;
    private array               $res = [];

    public function __construct(Application $application)
    {
        $this->application = $application;
        $this->client      = $this->application->getClient();
    }

    /**
     * @throws Exception
     */
    public function __call(string $name, array $arguments)
    {
        if (!method_exists($this, $name)) {
            return (new PayResult($this->res))->$name($arguments);
        }

        throw new Exception("inner error, method {$name} not found ", 502);
    }

    public function setOutTradeNo(string $out_trade_no)
    {
        $this->queryByTradeNo($out_trade_no);
        return $this;
    }

    /**
     * @param string $out_trade_no
     * @return array
     * @throws InvalidArgumentException
     * @throws InvalidConfigException
     * {
     * "amount": {
     * "currency": "CNY",
     * "payer_currency": "CNY",
     * "payer_total": 1,
     * "total": 1
     * },
     * "appid": "wxdace645e0bc2cXXX",
     * "attach": "",
     * "bank_type": "OTHERS",
     * "mchid": "1900006XXX",
     * "out_trade_no": "44_2126281063_5504",
     * "payer": {
     * "openid": "o4GgauJP_mgWEWictzA15WT15XXX"
     * },
     * "promotion_detail": [],
     * "success_time": "2021-03-22T10:29:05+08:00",
     * "trade_state": "SUCCESS",
     * "trade_state_desc": "支付成功",
     * "trade_type": "JSAPI",
     * "transaction_id": "4200000891202103228088184743"
     * }
     */
    public function queryByTradeNo(string $out_trade_no): array
    {
        $response  = $this->client->get("v3/pay/transactions/out-trade-no/{$out_trade_no}", [
            'query' => [
                'mchid' => $this->application->getMerchant()->getMerchantId(),
            ],
        ]);
        $this->res = $response->toArray();
        return $this->res;
    }

    public function setTransactionId(string $transaction_id)
    {
        $this->queryByTransactionId($transaction_id);
        return $this;
    }

    /**
     * @throws InvalidArgumentException
     * @throws InvalidConfigException
     */
    public function queryByTransactionId(string $transaction_id): array
    {
        $response  = $this->client->get("v3/pay/transactions/id/{$transaction_id}", [
            'query' => [
                'mchid' => $this->application->getMerchant()->getMerchantId(),
            ],
        ]);
        $this->res = $response->toArray();
        return $this->res;
    }

    public function getQueryResult(): array
    {
        return $this->res;
    }
}